<script lang="ts" setup>
import type { EChartsOption } from 'echarts'
import { computed, ref, unref, onMounted, onBeforeUnmount, onActivated, watch, nextTick } from 'vue'
import { debounce } from 'lodash-es'
import 'echarts-wordcloud'
import { isString } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'

// Import echarts dynamically to avoid issues
let echarts: any = null
try {
  echarts = require('echarts')
} catch (e) {
  console.warn('ECharts not found, component may not work properly')
}

defineOptions({ name: 'EChart', inheritAttrs: false })

const { getPrefixCls, variables } = useDesign()

const prefixCls = getPrefixCls('echart')

export interface EchartProps {
  options: EChartsOption
  width?: number | string
  height?: number | string
  theme?: 'light' | 'dark' | string
  isDark?: boolean
}

const props = withDefaults(defineProps<EchartProps>(), {
  width: '100%',
  height: '400px',
  theme: 'light',
  isDark: false
})

const theme = computed(() => {
  return props.isDark ? 'dark' : props.theme || 'light'
})

const options = computed(() => {
  return Object.assign({}, props.options, {
    darkMode: props.isDark
  })
})

const elRef = ref<HTMLElement>()

let echartRef: any = null

const contentEl = ref<Element>()

const styles = computed(() => {
  const width = isString(props.width) ? props.width : `${props.width}px`
  const height = isString(props.height) ? props.height : `${props.height}px`

  return {
    width,
    height
  }
})

const initChart = () => {
  if (unref(elRef) && echarts) {
    echartRef = echarts.init(unref(elRef), unref(theme))
    if (unref(options)) {
      echartRef.setOption(unref(options))
    }
  }
}

const setOption = (newOptions?: EChartsOption) => {
  if (echartRef) {
    echartRef.clear()
    echartRef.setOption(newOptions || unref(options))
  }
}

const resizeChart = () => {
  if (echartRef) {
    echartRef.resize()
  }
}

watch(
  () => props.options,
  (options) => {
    if (echartRef && options) {
      echartRef.setOption(options)
    }
  },
  {
    deep: true
  }
)

watch(
  () => unref(theme),
  () => {
    if (echartRef) {
      echartRef.dispose()
      initChart()
    }
  }
)

const resizeHandler = debounce(() => {
  resizeChart()
}, 100)

const contentResizeHandler = async (e: TransitionEvent) => {
  if (e.propertyName === 'width') {
    resizeHandler()
  }
}

onMounted(async () => {
  await nextTick()
  initChart()

  window.addEventListener('resize', resizeHandler)

  // Safe content element detection
  try {
    contentEl.value = document.getElementsByClassName(`${variables.namespace}-layout-content`)[0]
    unref(contentEl) &&
      (unref(contentEl) as Element).addEventListener('transitionend', contentResizeHandler)
  } catch (e) {
    console.warn('Layout content element not found')
  }
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandler)
  unref(contentEl) &&
    (unref(contentEl) as Element).removeEventListener('transitionend', contentResizeHandler)
  if (echartRef) {
    echartRef.dispose()
    echartRef = null
  }
})

onActivated(() => {
  resizeChart()
})

defineExpose({
  setOption,
  getInstance: () => echartRef,
  resize: resizeChart
})
</script>

<template>
  <div
    ref="elRef"
    :class="[$attrs.class, prefixCls]"
    :style="[styles, $attrs.style]"
  ></div>
</template>
